import subprocess
import os
import json
import subprocess
from common import ffmpeg_executable_cmd, ffprobe_executable_cmd


class VideoConverter:
    """视频转换器"""
    
    def __init__(self):
        pass
    
    def _validate_dimensions(self, width, height, media_type="视频文件"):
        """验证尺寸是否满足要求"""
        if width < 720 or height < 1280:
            raise Exception(f"{media_type}清晰度不够，宽度：{width}，高度：{height}")

    def _calculate_crop_params(self, width, height, target_w=1080, target_h=1920):
        """计算裁剪参数"""
        # 计算缩放比例，短边对齐
        scale_w = target_w / width
        scale_h = target_h / height
        scale = max(scale_w, scale_h)  # 确保短边对齐

        # 计算缩放后尺寸
        new_w = int(width * scale)
        new_h = int(height * scale)

        # 计算裁剪起点，居中裁剪
        crop_x = max(0, (new_w - target_w) // 2)
        crop_y = max(0, (new_h - target_h) // 2)

        return new_w, new_h, crop_x, crop_y

    def _get_output_path(self, input_path, suffix="_converted", extension=None):
        """生成输出文件路径"""
        base, ext = os.path.splitext(input_path)
        if extension:
            ext = f".{extension}"
        return f"{base}{suffix}{ext}"

    def convert_video(self, input_path):
        """转换视频文件"""
        # 先用ffprobe获取视频宽高
        ffprobe_cmd = [
            ffprobe_executable_cmd,
            "-v", "error",
            "-select_streams", "v:0",
            "-show_entries", "stream=width,height",
            "-of", "csv=p=0:s=x",
            input_path
        ]
        
        try:
            output = subprocess.check_output(ffprobe_cmd, stderr=subprocess.STDOUT).decode().strip()
            width, height = map(int, output.split('x'))
        except Exception as e:
            raise Exception(f"无法获取视频信息，文件可能异常。\n错误：{e}")

        # 验证尺寸
        self._validate_dimensions(width, height, "视频")

        # 计算裁剪参数
        new_w, new_h, crop_x, crop_y = self._calculate_crop_params(width, height)
        target_w, target_h = 1080, 1920

        # 输出文件路径
        output_file = self._get_output_path(input_path, extension="mp4")

        # ffmpeg命令，转换为网页兼容的mp4格式，1080x1920分辨率，30帧率
        ffmpeg_cmd = [
            ffmpeg_executable_cmd,
            "-i", input_path,
            "-vf", f"scale={new_w}:{new_h},crop={target_w}:{target_h}:{crop_x}:{crop_y}",
            "-c:v", "libx264",  # 使用H.264编码，网页兼容
            "-preset", "medium",  # 编码预设
            "-crf", "23",  # 质量设置
            "-r", "30",  # 设置帧率为30fps
            "-c:a", "aac",  # 音频编码为AAC，网页兼容
            "-b:a", "128k",  # 音频比特率
            "-movflags", "+faststart",  # 优化网页播放
            "-y",
            output_file
        ]

        try:
            subprocess.check_output(ffmpeg_cmd, stderr=subprocess.STDOUT)
            return output_file
        except subprocess.CalledProcessError as e:
            raise Exception(f"转换失败，错误信息：\n{e.output.decode()}")